﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using ServiceConfigTool;
using RFIDReaderDll; 
using SocketSuperLib;
using smforj.common.util;

namespace SafeDoorService
{
    /// <summary>
    /// 安全门控制服务程序
    /// </summary>
    public partial class SafeDoorService : ServiceBase
    {
        /// <summary>
        /// 日志
        /// </summary>
        private LogManage log = new LogManage();
        /// <summary>
        /// 检测安全门Timer
        /// </summary>
        private System.Timers.Timer checkSafeDoor = null;
        /// <summary>
        /// 安全门控制类
        /// </summary>
        private RFIDClient reader = null;
        /// <summary>
        /// SIP
        /// </summary>
        private IClient client = null;
        /// <summary>
        /// 本地数据库
        /// </summary>
        private BookService bookService = null;
        /// <summary>
        /// 是否连接设备
        /// </summary>
        private Boolean isOpen = false;
        private Boolean isStart = false;
        /// <summary>
        /// 消息队列
        /// </summary>
        private List<RFIDBook> queue = null;
        /// <summary>
        /// 判断线程
        /// </summary>
        private Thread myThread = null; 



        public SafeDoorService()
        {
            InitializeComponent();
            queue = new List<RFIDBook>();
            bookService = new BookServiceImpl();
        }


        #region 读卡器操作
        private void AutoConnect()
        {
            log.Info("正在打开端口"); 
            reader = new RFIDClient(); 
            reader.OnDisconnect += new EventHandler<DisconnectEventArgs>(reader_OnDisconnect);
            reader.OnErrorcallback += new EventHandler<ErrorReportEventArgs>(reader_OnErrorcallback);
            reader.OnInventoryReport += new EventHandler<InventoryReportEventArgs>(reader_OnInventoryReport);  
            try
            {
                String ip = ConfigurationManager.AppSettings["SafeDoorIp"];
                String port = ConfigurationManager.AppSettings["SafeDoorPort"];
                reader.Connect(ip, (ushort)Convert.ToInt32(port));
                isOpen = true;
                log.Info("打开端口成功"); 
            }
            catch (Exception ex)
            {
                log.Error("打开设备失败" + ex.Message);
                isOpen = false;
            }

            try
            {
                //设置天线
                Antena();
            }
            catch (Exception ex)
            {
                log.Error("设置设备天线失败" + ex.Message); 
            }
        
        }
        
        /// <summary>
        /// 关闭设备
        /// </summary>
        private void AutoDisconnect()
        {
            try
            {
                reader.Disconnect(); 
            }
            catch (Exception ex)
            {
                log.Error("关闭设备失败" + ex.Message);
                isOpen = true;
            }
            finally
            {
                reader = null;
                isOpen = false;
                isStart = false;
                GC.Collect();
            }
        }


        private void Open()
        {
            log.Info("正在启动盘点");
            try
            { 
                int iRes = reader.StartPerioInventory(); 
                if(iRes == 0)
                    isStart = true;
                else
                    isStart = false; 
                log.Info("启动盘点成功");
            }
            catch (Exception ex)
            {
                log.Error("启动盘点异常：" + ex.Message);
                isStart = false;
            }
        }

        private void Shutdown()
        {
            log.Info("正在关闭盘点");
            try
            {
                if (isStart)
                    reader.StopPeriodInventory();
                //isOpen = false;
                isStart = false; 
                log.Info("关闭盘点成功");
            }
            catch (Exception ex)
            {
                log.Error("关闭设备异常：" + ex.Message);
                //isOpen = true;
                isStart = true;
            } 
        }

        private Boolean isBuzzing = false;
        /// <summary>
        /// 蜂鸣
        /// </summary>
        /// <param name="obj"></param>
        private void Buzzing(object obj)
        {
            isBuzzing = true;
            int times = Convert.ToInt32(ConfigurationManager.AppSettings["Times"]);
            for (int i = 0; i < times; i++)
            {
                Alert();
                Thread.Sleep(1000);
            }
            isBuzzing = false;
        }
        
        private void Alert()
        {
            try
            {
                SET_GPO_PARAM param = new SET_GPO_PARAM();
                param.level1 = 0;
                param.level2 = 1;
                param.level3 = 0;
                param.level4 = 0;
                int i = 5;
                while (i > 0)
                {
                    if (i % 2 == 0)
                    {
                        param.level2 = 0;
                        reader.SetGpO(param);
                        Thread.Sleep(50);
                    }
                    else
                    {
                        param.level2 = 1;
                        reader.SetGpO(param);
                        Thread.Sleep(500);
                    }
                    i--;
                }
                param.level2 = 0;
                reader.SetGpO(param);
            }
            catch (Exception ex)
            {
                log.Error("执行蜂鸣异常："+ex.Message);
            }
        }


        private void Antena()
        {
            if (reader == null)
                return;
            log.Info("正在设置天线");
            //获取状态
            DEVICE_ANAINFO_STATUS_RESULT status = new DEVICE_ANAINFO_STATUS_RESULT();
            SET_ALLANTENNA_PARAM antena = new SET_ALLANTENNA_PARAM(); 
            int ret = reader.GetAntena(ref status);
            if (0 == ret)
            {

                antena.ant1.bEnable = status.AnaStatus == "1" ? true : false;
                antena.ant2.bEnable = status.AnaStatus2 == "1" ? true : false;
                antena.ant3.bEnable = status.AnaStatus3 == "1" ? true : false;
                antena.ant4.bEnable = status.AnaStatus4 == "1" ? true : false; 

                antena.ant1.nPower = Convert.ToInt32(status.TransmitPower);
                antena.ant2.nPower = Convert.ToInt32(status.TransmitPower2);
                antena.ant3.nPower = Convert.ToInt32(status.TransmitPower3);
                antena.ant4.nPower = Convert.ToInt32(status.TransmitPower4);

                antena.ant1.nDwellTime = Convert.ToInt32(status.DwellTime);
                antena.ant2.nDwellTime = Convert.ToInt32(status.DwellTime2);
                antena.ant3.nDwellTime = Convert.ToInt32(status.DwellTime3);
                antena.ant4.nDwellTime = Convert.ToInt32(status.DwellTime4);

                antena.ant1.nInvCycle = Convert.ToInt32(status.NumInvCyc);
                antena.ant2.nInvCycle = Convert.ToInt32(status.NumInvCyc2);
                antena.ant3.nInvCycle = Convert.ToInt32(status.NumInvCyc3);
                antena.ant4.nInvCycle = Convert.ToInt32(status.NumInvCyc4);

            }

            antena.ant1.nPower = Convert.ToInt32(ConfigurationManager.AppSettings["Ant1"]);
            antena.ant2.nPower = Convert.ToInt32(ConfigurationManager.AppSettings["Ant2"]);
            antena.ant3.nPower = Convert.ToInt32(ConfigurationManager.AppSettings["Ant3"]);
            antena.ant4.nPower = Convert.ToInt32(ConfigurationManager.AppSettings["Ant4"]);

            reader.SetAntenna(ref antena);
            log.Info("正在天线完成");
        }
        #endregion

        #region 事件处理
        private void reader_OnInventoryReport(object sender, InventoryReportEventArgs e)
        { 
            try
            {
                TagReport report = e.Report;
                foreach (Tag tag in report.Tags)
                {
                    log.Info("EPC  " + tag.Epc);
                    AddEPC(tag.Epc);
                }
            }
            catch (Exception ex)
            {
                log.Error("reader_OnInventoryReport异常："+ex.Message);
            }
        }

        private void AddEPC(String _epc)
        {
            lock (queue)
            {
                RFIDBook book = queue.Find(delegate(RFIDBook _book) { return _book.RRID == _epc; });
                if (book == null)
                    queue.Add(new RFIDBook() { RRID = _epc, ReadDate = DateTime.Now });
                else
                    book.ReadDate = DateTime.Now; 
            }
        }

        private void reader_OnErrorcallback(object sender, ErrorReportEventArgs e)
        {
            log.Error("读取异常：" + e.ReaderIdentity + "  Error Code ：" + e.ErrorCode + "   Mac Error:" + e.MacError);
            reader = null;
        }

        private void reader_OnDisconnect(object sender, DisconnectEventArgs e)
        {
            log.Error("读写器断开");
            isStart = isOpen = false;
            reader = null;
        }

        #endregion

        protected override void OnStart(string[] args)
        {
            log.Info("服务正在启用....");
            //启动Socket SIp2
            string[] stra = ConfigurationManager.AppSettings["sip2"].ToString().Split('|');
            client = ClientFactory.createClient(stra[0], Convert.ToInt32(stra[1])); 
            //检测安全门状态
            myThread = new Thread(new ThreadStart(CheckStatus));
            myThread.Start(); 
            //AutoConnect();   
            checkSafeDoor = new System.Timers.Timer();
            checkSafeDoor.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalTime"]) * 100;
            checkSafeDoor.Elapsed += new ElapsedEventHandler(checkSafeDoor_Elapsed);  
            checkSafeDoor.Enabled = true;  
            log.Info("服务启用成功....");
        }

        private void CheckStatus()
        {
            log.Info("CheckStatus启动...");
            Thread.Sleep(500);
            DEVICE_STATUS_RESULT status = new DEVICE_STATUS_RESULT();
            while (true)
            {
                //未打开进行打开
                if (reader == null || !isOpen)
                    AutoConnect();
                //查看安全门状态
                int ret = 0;
                try
                {
                    ret = reader.GetReaderInfo(ref status);
                }
                catch (Exception ex)
                {
                    log.Error("安全门状态异常:"+ex.Message);
                    ret = -1;
                } 
                //已经打开未启动，进行启动操作
                if (ret == 0 && !isStart && isOpen)
                    Open();
                //状态异常，进行销毁操作
                if (ret != 0)
                {
                    Shutdown();
                    AutoDisconnect();
                }
                //30秒测试一次 
                Thread.Sleep(1000 * 30);
            }
        } 
            
        protected override void OnStop()
        {
            log.Info("服务正在停止....");
            Shutdown();
            AutoDisconnect();
        } 

        #region Timer执行方法
        /// <summary>
        /// 线程阻塞
        /// </summary>
        private bool IsGetting = false; 

        protected void checkSafeDoor_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (!IsGetting)
            {
                IsGetting = true; 
                try
                {
                    lock (queue)
                    {
                        Boolean alert = false;
                        //查看是否要执行凤鸣
                        //校验UID是否要报警
                        foreach (RFIDBook book in queue)
                        {
                            CBookInfo bookinfo = bookService.getBook(book.RRID);
                            log.Info("bookinfo IsBorrow：" + bookinfo.IsBorrow);
                            //未借阅可能利用图书管理软件进行了借阅
                            if (bookinfo.IsBorrow != 1 && !string.IsNullOrEmpty(bookinfo.Barcode))
                            {
                                //查看图书管理软件的借阅情况
                                String sendMsg = SIP2Msg.BookInfoMsg(bookinfo.Barcode);
                                String response = client.SendAndReturnMsg(sendMsg);

                                log.Info("response ：" + response);
                                log.Info("response.IndexOf(\"CM\") ：" + response.IndexOf("CM"));
                                log.Info("response.IndexOf(\"CJ\") ：" + response.IndexOf("CJ"));
                                //未借阅
                                if (!string.IsNullOrEmpty(response) && response.IndexOf("CM") == -1 && response.IndexOf("CJ") == -1) 
                                    alert = true; 
                                //返回信息错误时不报警
                            }
                            //已经借阅不报警
                        }

                        if (alert && !isBuzzing) 
                            ThreadPool.QueueUserWorkItem(new WaitCallback(Buzzing));//蜂鸣 
                        queue.Clear();
                    }
                }
                catch (Exception ex)
                {
                    log.Error("处理信息异常：" + ex.Message);
                }
                IsGetting = false;
            }
        }
        #endregion  
    }
     
}
